Skip to content

Conversation

@awillenbuecher-xq-tec
Copy link
Contributor

@awillenbuecher-xq-tec awillenbuecher-xq-tec commented Nov 25, 2025

This PR adds two data structures to the Rust base libs: an ABI-compatible and a fixed-capacity vector. Refer to the feature request for more information about ABI compatibility.

Notes for Reviewer

Pre-Review Checklist for the PR Author

  • PR title is short, expressive and meaningful
  • Commits are properly organized
  • Relevant issues are linked in the References section
  • Tests are conducted
  • Unit tests are added

Checklist for the PR Reviewer

  • Commits are properly organized and messages are according to the guideline
  • Unit tests have been written for new behavior
  • Public API is documented
  • PR title describes the changes

Post-review Checklist for the PR Author

  • All open points are addressed and tracked via issues

References

@github-actions
Copy link

github-actions bot commented Nov 25, 2025

License Check Results

🚀 The license check job ran with the Bazel command:

bazel run //:license-check

Status: ⚠️ Needs Review

Click to expand output
[License Check Output]
Extracting Bazel installation...
Starting local Bazel server (8.4.2) and connecting to it...
INFO: Invocation ID: c809020c-27de-4c68-aa90-75225b16cceb
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
DEBUG: Rule 'rust_qnx8_toolchain+' indicated that a canonical reproducible form can be obtained by modifying arguments integrity = "sha256-eQOopREOYCL5vtTb6c1cwZrql4GVrJ1FqgxarQRe1xs="
DEBUG: Repository rust_qnx8_toolchain+ instantiated at:
  <builtin>: in <toplevel>
Repository rule http_archive defined at:
  /home/runner/.bazel/external/bazel_tools/tools/build_defs/repo/http.bzl:431:31: in <toplevel>
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
Computing main repo mapping: 
WARNING: For repository 'aspect_rules_lint', the root module requires module version [email protected], but got [email protected] in the resolved dependency graph. Please update the version in your MODULE.bazel or set --check_direct_dependencies=off
WARNING: For repository 'buildifier_prebuilt', the root module requires module version [email protected], but got [email protected] in the resolved dependency graph. Please update the version in your MODULE.bazel or set --check_direct_dependencies=off
Computing main repo mapping: 
Loading: 
Loading: 0 packages loaded
Loading: 0 packages loaded
Loading: 0 packages loaded
    currently loading: 
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)

Analyzing: target //:license-check (27 packages loaded, 9 targets configured)

Analyzing: target //:license-check (127 packages loaded, 869 targets configured)

Analyzing: target //:license-check (139 packages loaded, 2557 targets configured)

Analyzing: target //:license-check (142 packages loaded, 2567 targets configured)

Analyzing: target //:license-check (147 packages loaded, 2616 targets configured)

Analyzing: target //:license-check (149 packages loaded, 2740 targets configured)

INFO: Analyzed target //:license-check (152 packages loaded, 4876 targets configured).
[7 / 14] checking cached actions
INFO: From Generating Dash formatted dependency file ...:
WARNING: No packages found in Cargo.lock.
INFO: Successfully converted 0 packages from Cargo.lock to bazel-out/k8-fastbuild/bin/formatted.txt
INFO: Found 1 target...
Target //:license.check.license_check up-to-date:
  bazel-bin/license.check.license_check
  bazel-bin/license.check.license_check.jar
INFO: Elapsed time: 28.207s, Critical Path: 0.47s
INFO: 14 processes: 5 disk cache hit, 9 internal.
INFO: Build completed successfully, 14 total actions
INFO: Running command line: bazel-bin/license.check.license_check ./formatted.txt <args omitted>
usage: org.eclipse.dash.licenses.cli.Main [-batch <int>] [-cd <url>]
       [-confidence <int>] [-ef <url>] [-excludeSources <sources>] [-help] [-lic
       <url>] [-project <shortname>] [-repo <url>] [-review] [-summary <file>]
       [-timeout <seconds>] [-token <token>]

@github-actions
Copy link

The created documentation from the pull request is available at: docu-html

Copy link
Contributor

@pawelrutkaq pawelrutkaq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once we finihs I would ping this to baselibs team to have a look if interested

"editor.defaultFormatter": "rust-lang.rust-analyzer",
"editor.formatOnSave": true,
"editor.rulers": [
100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this shall be aligned with rustfmt

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -0,0 +1,20 @@
// *******************************************************************************
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we call this folder abi_datatypes _cd is bit misterious.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now we have to change that and move generic part to seprate thing, and live here only ABI types, or vice versa or ?

src/abi_cd/BUILD Outdated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing bazel build

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

rustfmt.toml Outdated


match_block_trailing_comma = true
max_width = 100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shall this be 120-150. 100 is bit low.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer 100, because I like to put two tabs side-by-side. However, I've changed it back to 150 – maybe I need a bigger screen 😉

@@ -0,0 +1,27 @@
[package]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Baselibs Rust shall be dependent less.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and I would keep effort low on cargo so would derive everything from workspace (desc, versions etc)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not possible, I need to import those crates to be able to derive PlacementDefault and Reloc on the types.

Copy link
Contributor

@pawelrutkaq pawelrutkaq Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to do it differently. We will import baselib_rust into comm API and implement Reloc there. is that ok ? We will also define placement trait in there so we can implement it there.

}

#[test]
fn flags() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hard to get what this name means

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've renamed it to abi/fixed_vec_is_full_and_is_empty()

len: u32,
/// The index of the next element to be popped.
read_pos: u32,
elements: [MaybeUninit<T>; CAPACITY],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't replacing len and elements with AbiVec be better?

Copy link
Contributor Author

@awillenbuecher-xq-tec awillenbuecher-xq-tec Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In an AbiVec, the valid elements are always in slots 0...len-1, but this typically isn't the case for AbiQueue: in a queue, they could be in slots 1...len or 2...len+1, and they might even be in two separate ranges at the beginning and the end of the slots.

Also, replacing len and elements with AbiVec would change the memory layout of the struct.

(first, second)
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is semantic in those calls? We cannot easilly say where beggining or end is. This opens a question whether we shall expose this api at ASIL-B level..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is analogous to VecDeque::as_slices. The purpose is to provide very efficient access to all queued elements.

I could write a more detailed description into the docs of this method.

///
/// * `start <= end <= CAPACITY` must hold
/// * all storage slots in the range `start..end` must be valid
const unsafe fn subslice(&self, start: usize, end: usize) -> *const [T] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move private to bottom of impl block.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -0,0 +1,398 @@
// *******************************************************************************
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will wait till we fix vector as his have same questions ;)

/// # Safety
///
/// `index < self.capacity()` must hold.
unsafe fn element(&self, index: u32) -> &MaybeUninit<T>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this does not need to be unsafe or ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must be unsafe, because if index >= capacity, this will result in an out-of-bounds array access.

/// # Safety
///
/// `index < self.capacity()` must hold.
unsafe fn element_mut(&mut self, index: u32) -> &mut MaybeUninit<T>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sam here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above

impl<T, const CAPACITY: usize> Inline<T, CAPACITY> {
// Compile-time check. This condition _must_ be referenced in every function that depends on it,
// otherwise it will be removed during monomorphization.
const CHECK_CAPACITY: () = assert!(0 < CAPACITY && CAPACITY <= (u32::MAX as usize));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we limit elems to u32 or use u64 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't there's a realistic use case for a having more than 4.2 billion elements in a single ABI compatible container, is there? Similar for the non-ABI, fixed capacity containers – even with u8 as elements, that would require reserving more than 4 GiB of memory just for one vector in your embedded system, and it quickly becomes worse when you want to store anything "interesting" in it 😉

debug_assert!(index < self.capacity);
let index = index as usize;
// SAFETY: `index` is in-bounds of the memory allocation, as per the pre-condition on the trait method.
unsafe { self.elements.add(index).cast::<MaybeUninit<T>>().as_ref() }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add that maybeUninit is repr transparent thats why casting form T is ok ?

}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need UT for those here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -0,0 +1,20 @@
// *******************************************************************************
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now we have to change that and move generic part to seprate thing, and live here only ABI types, or vice versa or ?

///
/// The vector can hold between 0 and `CAPACITY` elements, and behaves similarly to Rust's `Vec`,
/// except that it allocates memory immediately on construction, and can't shrink or grow.
pub struct FixedVec<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RuntimFixedVec
NonRelocVec

or as it is ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I'll just leave it at FixedVec.


impl<T> Drop for FixedVec<T> {
fn drop(&mut self) {
if needs_drop::<T>() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redudant, this is in clear() already.

load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")

rust_library(
name = "abi-types-common",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think bazel target shall be underscore. and you may use crate_name to define it rust wise if you need

@awillenbuecher-xq-tec awillenbuecher-xq-tec force-pushed the adwi_abivec branch 2 times, most recently from 9f1d3a3 to e630a04 Compare November 28, 2025 09:07
@awillenbuecher-xq-tec awillenbuecher-xq-tec changed the title ABI compatible vector and queue data structures ABI compatible vector Nov 28, 2025
use crate::storage::Storage;

#[repr(C)]
pub struct GenericVec<T, S: Storage<T>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we provide somewhere alias for FixedSizeVec ? The users may want to also use compile time vec too.

name = "containers",
srcs = glob(["**/*.rs"]),
edition = "2024",
version = "0.1.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not needed for bazel as we anyway version bazel module only

@awillenbuecher-xq-tec awillenbuecher-xq-tec changed the title ABI compatible vector ABI-compatible and fixed-capacity vectors Nov 28, 2025
@4og 4og merged commit 145c734 into eclipse-score:main Dec 2, 2025
11 checks passed
@awillenbuecher-xq-tec awillenbuecher-xq-tec deleted the adwi_abivec branch December 8, 2025 11:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Rust] ABI-compatible vector [Rust] Fixed-capacity vector

3 participants